DropWizard中JDBI 3的onDemand与attach实例的连接事务复用问题
JDBI 场景问题解答
结论
你给出的代码场景中,dao1的两次insert操作会各自独立创建新连接、独立事务,dao2的两次insert操作会复用try代码块中打开的同一个连接,二者不会共享连接或事务。
原理说明
dbi.onDemand()生成的DAO是动态代理实例,每次调用代理的DAO方法时,都会独立从连接池申请新的Handle,方法执行完成后立刻关闭该Handle,默认单个方法调用就是独立的自动提交事务。它不会主动检测当前线程是否存在其他活跃Handle,也不会复用其他逻辑中打开的Handle,与同线程的attach生成的DAO完全隔离。handle.attach()生成的DAO与创建它的Handle强绑定,所有DAO方法调用都会复用该Handle持有的数据库连接,事务生命周期完全和该Handle绑定。- 你示例中的写法是手动打开Handle,没有做线程上下文绑定,所以onDemand生成的dao1完全感知不到同线程内dao2对应的Handle存在。
对应你的代码执行流程
额外提示:JDBI的Handle默认是自动提交模式,如果你需要让dao2的多个insert归入同一个事务,需要主动调用
handle.begin()开启显式事务,操作完成后手动commit()/rollback()。
- 第一个
dao1.insert():申请新连接→执行insert→自动提交→释放连接 - 两次
dao2.insert():复用try块中打开的Handle连接,自动提交模式下每个insert执行后自动提交,若开启显式事务则归入同一事务 - 第二个
dao1.insert():再次申请新连接→执行insert→自动提交→释放连接
扩展说明
如果需要让onDemand的DAO复用当前线程的活跃连接/事务,可以用dbi.useTransaction()或dbi.inTransaction()包裹业务代码,该场景下代码块内调用的onDemand DAO会自动复用当前事务对应的Handle。
内容的提问来源于stack exchange,提问作者mjs
相关产品推荐
相关产品推荐

