jdbc 系列文章列表, 请查看目录: 《jdbc学习笔记》
1. jdbc 事务嵌套
jdbc 提供了事务保存点的概念, 用于指定事务的回滚时间点.在执行回滚操作时, 可指定回滚到哪个保存点. 这这保存点之间的所有操作都将回滚如果执行回滚操作时, 不指定保存点, 则将该连接的所有操作全部回滚通过设置事务的保存点, 可实现事务嵌套. spring的事务传播策略Propagation.NESTED, 就是借助于此实现的.
1.1 相关API
方法签名描述
Savepoint setSavepoint()创建事务保存点, 名称自动生成Savepoint setSavepoint(String name)创建事务保存点, 指定所有名称void rollback(Savepoint savepoint)指定回滚某个保存点到当前的所有操作void rollback()指定回滚某个保存点到当前的所有操作void releaseSavepoint(Savepoint savepoint)mysql驱动并为提供实现, 说明不支持此API
1.2 回滚至保存点
保存点回滚会将该保存点之后的所有操作进行回滚, 该保存点之前的操作不会进行回滚.
回滚至sp3, 则会回滚sql4的操作回滚至sp2, 则会回滚sql3, sql4的操作回滚至sp1, 则会回滚sql2, sql3, sql4的操作
sql1..
-------> SavePoint: sp1
sql2...
-------> SavePoint: sp2
sql3...
-------> SavePoint: sp3
sql4...
回滚至保存点: rollback(sp1/sp2/sp3/sp4);
commit();
2. 嵌套事务测试
使用嵌套事务时, 必须取消自动提交事务, 需要手工提交事务.
2.1 单个保存点
创建一个保存点, 保存点名称随机生成事务提交之前, 回滚至保存点sp1, 即将sp1之后的操作全部回滚.执行结果: 数据库只成功插入了1001 实体
@Test
public void test11() throws Exception
{
Connection connection
= DbConnUtil
.getConnection();
connection
.setAutoCommit(false);
BaseDao
.save(connection
, new UserPO(1001, "zhangsan", "123456"));
Savepoint sp1
= connection
.setSavepoint();
BaseDao
.save(connection
, new UserPO(1002, "lisi", "123456"));
connection
.rollback(sp1
);
connection
.commit();
}
2.2 创建多个保存点
创建多个保存点, sp1, sp2, sp3不指定保存点: 则全部回滚指定回滚至保存点sp1: 则只保存1001指定回滚至保存点sp2: 则保存1001, 1002指定回滚至保存点sp3: 则保存1001, 1002, 1003
@Test
public void test12() throws Exception
{
Connection connection
= DbConnUtil
.getConnection();
connection
.setAutoCommit(false);
BaseDao
.save(connection
, new UserPO(1001, "zhangsan", "123456"));
Savepoint sp1
= connection
.setSavepoint("sp1");
BaseDao
.save(connection
, new UserPO(1002, "lisi", "123456"));
Savepoint sp2
= connection
.setSavepoint("sp2");
BaseDao
.save(connection
, new UserPO(1003, "wangwu", "123456"));
Savepoint sp3
= connection
.setSavepoint("sp3");
BaseDao
.save(connection
, new UserPO(1004, "zhaoliu", "123456"));
connection
.rollback(sp3
);
connection
.commit();
}