取下经,各位在Java项目里是如何管理数据库连接的?

小灰狼 2018-02-07 08:13:26
一个Java EE 项目里的业务逻辑可能会比较复杂,一个业务逻辑处理不往往不会是简单地对一个表进行操作,而是一连串的操作,并且是要形成一个事务
那么在业务逻辑处理过程中,就要求所有的对数据库的处理都是使用同一个连接,这样才能保证事务一致性,并且确保连接被及时关闭回收

如果是在纯Java Web项目中,我一般会把连接的 autocommit 设置为 false,然后使用一个连接工厂类统一管理连接,并且把连接和线程进行绑定(这是借鉴了 Hibernate 的思路,但我在 mybatis 中也是这么封装的)。从工厂类中取到的所有连接全部都是绑定在当前线程上的,以此保证每个业务逻辑子程序中取到的都是同一个连接。然后在 servlet filter 中统一关闭与线程绑定的连接。
如此一来,程序员在得到连接时,只需要调用工厂类中的连接,最后关闭连接的操作就不用关注了,因为它们已经在 servlet filter 中统一做过了,只要不启动新线程、Timer 之类的东西。

如果不使用这种机制,或者项目不是一个 Java Web 项目,没有提供基于线程的监听机制。则上面说的办法就不管用了。
我所想到的是,把Connection 对象或者封装后的对象作为参数,传入到各个数据库访问的子程序中去,或者构建Dao对象是通过构造器参数传进去。
另外就是,如果业务逻辑复杂,在一次业务处理中会调用子程序,子程序会访问数据库,而子程序又会调用它的子程序,子子程序又会访问数据库。如果是这样,我现在形成的想法是,先把要用到的数据一次性读到内存中,逻辑处理过程中如果要写数据库,则先把数据在内存中修改,最后再一次性写入。这样避免在子程序、子子程序中传递Connection,降低数据库处理的复杂性。
...全文
689 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
X元素 2018-02-24
  • 打赏
  • 举报
回复
引用 3 楼 hemowolf 的回复:
[quote=引用 2 楼 u011619071 的回复:] 如果你操作的某条记录正好也被其他线程操作的话,写入内存这个动作就很危险,然后你还要再来一遍数据的行级锁实现; 其实spring的事务就可以实现你说的这种,子线程问题;
这种情况我会在写数据库时进行逻辑处理和判断 比如一个端口的库存,我可以在业务逻辑开始时读出当前库存,但是在最后更新库存时,是执行 update tablename set balance = balance -1 where id = ? and balance > 0 的操作,而不是简单地把最初读到的库存减1再写入。[/quote] 现在都讲究服务化,跟你说的这个端口库存是一样的,将公共资源进行统一管理,这种方式挺不错的,考虑好网络异常引发的一些异常情况;
小灰狼 2018-02-08
  • 打赏
  • 举报
回复
还有别的思路吗 希望有点收获
maradona1984 2018-02-07
  • 打赏
  • 举报
回复
引用 3 楼 hemowolf 的回复:
[quote=引用 2 楼 u011619071 的回复:] 如果你操作的某条记录正好也被其他线程操作的话,写入内存这个动作就很危险,然后你还要再来一遍数据的行级锁实现; 其实spring的事务就可以实现你说的这种,子线程问题;
这种情况我会在写数据库时进行逻辑处理和判断 比如一个端口的库存,我可以在业务逻辑开始时读出当前库存,但是在最后更新库存时,是执行 update tablename set balance = balance -1 where id = ? and balance > 0 的操作,而不是简单地把最初读到的库存减1再写入。[/quote] 你这种操作不具备通用性,还是弄个spring吧,这个还是挺复杂的,知道轮子怎么造就行了,也可以自己造个玩具来玩,但工作中还是用成熟的框架的好 而且你是否想说多数据源?
maradona1984 2018-02-07
  • 打赏
  • 举报
回复
你需要的仅仅是个spring
小灰狼 2018-02-07
  • 打赏
  • 举报
回复
引用 2 楼 u011619071 的回复:
如果你操作的某条记录正好也被其他线程操作的话,写入内存这个动作就很危险,然后你还要再来一遍数据的行级锁实现; 其实spring的事务就可以实现你说的这种,子线程问题;
这种情况我会在写数据库时进行逻辑处理和判断 比如一个端口的库存,我可以在业务逻辑开始时读出当前库存,但是在最后更新库存时,是执行 update tablename set balance = balance -1 where id = ? and balance > 0 的操作,而不是简单地把最初读到的库存减1再写入。
X元素 2018-02-07
  • 打赏
  • 举报
回复
如果你操作的某条记录正好也被其他线程操作的话,写入内存这个动作就很危险,然后你还要再来一遍数据的行级锁实现; 其实spring的事务就可以实现你说的这种,子线程问题;
maradona1984 2018-02-07
  • 打赏
  • 举报
回复
引用 6 楼 hemowolf 的回复:
[quote=引用 5 楼 maradona1984 的回复:] [quote=引用 3 楼 hemowolf 的回复:] [quote=引用 2 楼 u011619071 的回复:] 如果你操作的某条记录正好也被其他线程操作的话,写入内存这个动作就很危险,然后你还要再来一遍数据的行级锁实现; 其实spring的事务就可以实现你说的这种,子线程问题;
这种情况我会在写数据库时进行逻辑处理和判断 比如一个端口的库存,我可以在业务逻辑开始时读出当前库存,但是在最后更新库存时,是执行 update tablename set balance = balance -1 where id = ? and balance > 0 的操作,而不是简单地把最初读到的库存减1再写入。[/quote] 你这种操作不具备通用性,还是弄个spring吧,这个还是挺复杂的,知道轮子怎么造就行了,也可以自己造个玩具来玩,但工作中还是用成熟的框架的好 而且你是否想说多数据源?[/quote] 这篇文章应该是CSDN自动加上的:http://blog.csdn.net/gadbee5/article/details/23464923 看了之后感觉,spring 本质上还是把连接(或者其衍生对象)和当前线程进行绑定,这样在任何地方获取连接,都返回与线程绑定的那个对象即可。 这和我最开始说的办法没什么本质差别[/quote] 是没啥本质区别的,只是人家考虑的场景比你更全罢了,当然自己写更灵活
小灰狼 2018-02-07
  • 打赏
  • 举报
回复
引用 5 楼 maradona1984 的回复:
[quote=引用 3 楼 hemowolf 的回复:] [quote=引用 2 楼 u011619071 的回复:] 如果你操作的某条记录正好也被其他线程操作的话,写入内存这个动作就很危险,然后你还要再来一遍数据的行级锁实现; 其实spring的事务就可以实现你说的这种,子线程问题;
这种情况我会在写数据库时进行逻辑处理和判断 比如一个端口的库存,我可以在业务逻辑开始时读出当前库存,但是在最后更新库存时,是执行 update tablename set balance = balance -1 where id = ? and balance > 0 的操作,而不是简单地把最初读到的库存减1再写入。[/quote] 你这种操作不具备通用性,还是弄个spring吧,这个还是挺复杂的,知道轮子怎么造就行了,也可以自己造个玩具来玩,但工作中还是用成熟的框架的好 而且你是否想说多数据源?[/quote] 这篇文章应该是CSDN自动加上的:http://blog.csdn.net/gadbee5/article/details/23464923 看了之后感觉,spring 本质上还是把连接(或者其衍生对象)和当前线程进行绑定,这样在任何地方获取连接,都返回与线程绑定的那个对象即可。 这和我最开始说的办法没什么本质差别

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧