hibernate事务之数据库事务和系统事务

来源:互联网 发布:上海生活成本 知乎 编辑:程序博客网 时间:2024/04/28 01:51

hibernate事务之数据库事务和系统事务


数据库把工作单元的概念实现为一个数据库事务。数据库事务组合了数据库访问操作---也就是sql操作。所有sql语句都在一个事务内部执行;事务被确保以这两种方式之一终止:要么完全被提交(commit),要么完全被回滚(roll back)。因而,我们说数据库事务是原子性的。

 

为了在事务内部执行所有的数据库操作,必须给这个工作单元的范围做标记。必须启动事务,并在某个时间点提交变化。如果出现错误(在执行操作或者提交事务的时候),就必须回滚事务。把数据留在一致的状态中。这就是大家所知的事务划分。

 

一般来说,启动和终止事务的事务范围可以在应用程序代码中编程式地设置,或者声明式地设置。

--------------------

1. 编程式的事务划分

在非托管环境中,JDBC API被用来给事务范围做标记。通过在JDBC Connection中调用setAutoCommit(false)启动事务,并通过调用commit()终止它。可以在任何时候通过调用rollback()强制立即回滚。

在一个于几个数据库中操作数据的系统中,特定的工作单元涉及对不止一个资源的访问。既然如此,你就无法单独通过JDBC实现原子性。你需要可以在系统事务中处理几个资源的事务管理器。这样的事务处理系统公开了与开发人员进行交互的Java Transaction API(JTA)。JTA中的主API是UserTransaction接口,包含begin()和commit()系统事务的方法。

此外,hibernate应用程序中的编程式事务管理通过Hibernate Transaction接口公开给应用程序开发人员。你并没有被强制使用这个API---Hibernate也让你直接启动和终止JDBC事务,但不鼓励这种用法。因为它把代码绑定到了直接的JDBC。在JavaEE环境中,就可以使用JTA兼容的事务管理器,因此你应用调用JTA UserTransaction接口来编程式地启动和终止事务。然而,就像你可能已经猜到的,hibernate Transaction接口在JTA的顶层也有效。后面我们将介绍所有这些方法,并更详细地讨论可移植性的关注点。

 

让我们概括一下这些接口,以及什么时候使用它们:

. Java.sql.Connection---利用setAutoCommit(false),commit(),rollback()进行简单的JDBC事务划分。它可以但不应该被用在Hibernate应用程序中,因为它把应用程序绑定到了一个简单的JDBC环境。

. org.hibernate.Transaction---Hibernate应用程序中统一的事务划分。它适用于非托管的简单JDBC环境,也适用于以JTA作为底层系统事务服务的应用程序服务器。但是,它最主要的好处在于与持久化上下文管理的紧密整合---例如,你提交时Session被自动清除。持久化上下文也可以拥有这个事务的范围。如果你无法具备JTA兼容的事务服务,就使用java SE中的这个API.

. javax.transaction.UserTransaction---Java中编程式事务控制的标准接口,它是JTA的一部分。每当你具备JTA兼容的事务服务,并想编程式地控制事务时,它就应该成为你的首选。

------------------

2. 声明式事务划分 

声明式事务划分不需要额外的代码;并且从定义上来说,它解决了可移植性的问题。

在应用程序中,当你希望在一个事务内部进行工作的时候要进行声明(例如,在方法中使用注解)。然后处理这个关注点就是应用部署程序和运行时环境的责任了。Java中提供声明式事务服务的标准容器是EJB容器,这项服务也称作容器托管事务。

原创粉丝点击