
数据库事务、连接与java线程之间的关系
最近在处理事务和多线程时,比较困扰数据库事务,数据库连接以及java线程之间的关系。
问题1:事务和连接的关系?
回答:对于数据库事务来说先有一个连接,才能有事务,一个连接里可以有一次或多次事务的提交(自动提交或者手动提交)。对于java中的被transactional注解方法来说,这个被事务管理的方法中可能会使用多个连接。例如一个事务方法里嵌套一个propagation=required的事务方法时,外方法用一个连接,嵌套的方法用一个连接,并且是两个不同的事务。
问题2:连接和线程的关系?
回答:从debug代码看来,一个线程中有去 *** 作数据库,就会去CP获取一个数据库连接,如果此时CP中没有连接可用,就会等待,直到有连接为止。
问题3:一个事务中(transactional注解的方法内)如果开启了多个线程去执行其他的插入 *** 作,那么每个线程执行的插入 *** 作,和线程的caller方法中的插入 *** 作是同一个事务吗?
回答:不是同一个事务
解析:
1.如下图,一个transactional 注解的方法内,先做一次插入 *** 作,接着开了3个线程去分别处理插入任务
2.执行结果通过看debug日志可看出,在执行testTransAndConnection方法时获取了一个数据库连接,并开启了一个事务,并把事务设置为手动提交,然后进行插入 *** 作,插入 *** 作完成,就call起三个线程并且准备着手提交主方法里的事务了。
3.每个线程是创建了不同的sqlsession 去处理的,这里用的连接却都还是主方法释放的那个连接(这里都是同一个连接的原因是由于服务起来后,第一次去请求应用,此时数据库连接池还没有初始化完毕,池子里只有刚刚初始化好的一个连接,其他的连接还没来的及初始化出来,所以这里几个线程的 *** 作其实是大家都在等待并争用那唯一的一个数据库连接。等CP初始化完毕,如果再次触发一次请求就会发现:每个线程的sqlsession都是不同的连接)
是的。如果你只用到一个连接,这么理解是对的。数据库事务和连接之间不是一对一的关系,
即一个Tran中可以有多个连接,对多个实例进行 *** 作,
但是一个当Tran开始后,如果当前连接断掉,是不允许再重新连接的, 因为事务要保证执行的完整性。
所以断掉之后,就会执行回滚方法,然后让下一个事务进行。
如果一个事务中只有一个连接, 那么这个事务的所有 *** 作,都要在开始的连接中进行,直到结束, 否则就回滚。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)