在现在的OR方案和SPRING JDBC框架中,对数据库事务处理均是对java.sql.DataSource处理的。
大致思路是:在开始事务时,事务管理器会记录DataSource的连接,以后每个DAO从DataSource中getConnection()时,事务管理器会判断这个Connection是不是当前控制事务的子线程打开的,如果是,则记录并对此Connection进行事务处理,在commit和rollback事务时,会对所有打开的Connection进行Commit和rollback,最终清理所有Connection资源。
大伙可能知道,数据库对事务缓存是按会话区分的。一个Connection就是一个会话。举例说明:
maxid |
1 |
for(A、B){
1:取maxid;
其他操作
2:更新maxid++;
}
这假设的A、B两个完全相同的业务操作。每个操作下又有1、2两个DAO操作。
在执行 A.1时,取出最大值maxid=1
执行 A.2时,更新成maxid=2
扫行 B.1时,取出最大值max=? 这正确的应该是2,而实际取到的是1
这就有一个问题,B.1的结果是错误的。分析原因:因为上面三个步骤可能都是单独的Connection,在执行A.2后,该事务并未提交(因为大的事务未完成),