jdbc transaction
http://www.iteye.com/topic/142605
1、JavaBean中使用JDBC方式进行事务处理
在JDBC中怎样将多个SQL语句组合成一个事务呢?在JDBC中,打开一个连接对象Connection时,缺省是auto-commit模式,每个SQL语句都被当作一个事务,即每次执行一个语句,都会自动的得到事务确认。为了能将多个SQL语句组合成一个事务,要将auto-commit模式屏蔽掉。在auto-commit模式屏蔽掉之后,如果不调用commit()方法,SQL语句不会得到事务确认。在最近一次commit()方法调用之后的所有SQL会在方法commit()调用时得到确认。
public int delete(int sID) {
dbc = new DataBaseConnection();
Connection con = dbc.getConnection();
try {
con.setAutoCommit(false);// 更改JDBC事务的默认提交方式
dbc.executeUpdate("delete from bylaw where ID=" + sID);
dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
con.commit();//提交JDBC事务
con.setAutoCommit(true);// 恢复JDBC事务的默认提交方式
dbc.close();
return 1;
}
catch (Exception exc) {
con.rollBack();//回滚JDBC事务
exc.printStackTrace();
dbc.close();
return -1;
}
}
JTA 是事务服务的 J2EE 解决方案。本质上,它是描述事务接口(比如 UserTransaction 接口,开发人员直接使用该接口或者通过 J2EE 容器使用该接口来确保业务逻辑能够可靠地运行)的 J2EE 模型的一部分。JTA 具有的三个主要的接口分别是 UserTransaction 接口、TransactionManager 接口和 Transaction 接口。这些接口共享公共的事务操作,例如 commit() 和 rollback(), 但是也包含特殊的事务操作,例如 suspend(),resume() 和 enlist(),它们只出现在特定的接口上,以便在实现中允许一定程度的访问控制。例如,UserTransaction 能够执行事务划分和基本的事务操作,而 TransactionManager 能够执行上下文管理。
应用程序可以调用UserTransaction.begin()方法开始一个事务,该事务与应用程序正在其中运行的当前线程相关联。底层的事务管理器实际处理线程与事务之间的关联。UserTransaction.commit()方法终止与当前线程关联的事务。UserTransaction.rollback()方法将放弃与当前线程关联的当前事务。
public int delete(int sID) {
DataBaseConnection dbc = null;
dbc = new DataBaseConnection();
dbc.getConnection();
UserTransaction transaction = sessionContext.getUserTransaction();//获得JTA事务
try {
transaction.begin(); //开始JTA事务
dbc.executeUpdate("delete from bylaw where ID=" + sID);
dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
transaction.commit(); //提交JTA事务
dbc.close();
return 1;
}
catch (Exception exc) {
try {
transaction.rollback();//JTA事务回滚
}
catch (Exception ex) {
//JTA事务回滚出错处理
ex.printStackTrace();
}
exc.printStackTrace();
dbc.close();
return -1;
}
}
http://fengzl.iteye.com/blog/163551
Java代码
public class UserTransaction {
private static Map threadDbconnectionMap = new HashMap();
public void begin() {
dataSource.getConnection().setAutoCommit(false);
threadDbConnectionMap.put(Thread.currentThread(), dataSource.getConnection());
dataSource.getConnection().startTransaction();
}
public void commit() {
dataSource.getConnection().commitTransaction();
threadDbConnectionMap.remove(Thread.currentThread());
}
}
public class DataSource {
private static Map threadDbConnectionMap = new HashMap();
public Connection getConnection() {
if(threadDbConnectionMap.get(Thread.currentThread()) == null) {
threadDbConnectionMap.put(Thread.currentThread(), DBCONNECTION_POOL.getConnection);
}
return (Connection)threadDbConnectionMap.get( Thread.currentThread());
}
}
public class UserTransaction {
private static Map threadDbconnectionMap = new HashMap();
public void begin() {
dataSource.getConnection().setAutoCommit(false);
threadDbConnectionMap.put(Thread.currentThread(), dataSource.getConnection());
dataSource.getConnection().startTransaction();
}
public void commit() {
dataSource.getConnection().commitTransaction();
threadDbConnectionMap.remove(Thread.currentThread());
}
}
public class DataSource {
private static Map threadDbConnectionMap = new HashMap();
public Connection getConnection() {
if(threadDbConnectionMap.get(Thread.currentThread()) == null) {
threadDbConnectionMap.put(Thread.currentThread(), DBCONNECTION_POOL.getConnection);
}
return (Connection)threadDbConnectionMap.get( Thread.currentThread());
}
}
UserTransaction的机制就是建立一个currentThread和一个 DBconnection的map,使得在同一个thread下的所有db operation使用同一个connection,这样通过背后的同一个connection的commit或rollback来保证 transaction的atomic
1。由于你只是使用了web server,没有采用application server,你的application又需要提供Transaction的control,唯一的办法是提供你自己的Transaction Manager,而不是使用UserTransaction(正如你所说的,web server不提供UserTransaction)。UserTransaction也是一种TransactionManager,由J2EE Container提供。
2。你的“dbConnection.setAutoCommit(true)”这个调用是错误的。如果你调用该语句,dbConnection就会每次execute一句sql以后自动commit了,这样你的程序中本身需要放在同一个transaction中执行的代码分散在了好几个不同的transaction中执行了,就会导致partial update的问题,data consistency就没有办法保证。
3。“死锁”的问题应该是你程序中的问题,而不应该归咎于dbConnection是否是 auto commit的。我在以前曾经写过一个自己的TransactionManager,就是通过建立一个Thread和dbConnection的map来实现的。刚开始测试这个TransactionManager的时候,也是经常出现“死锁”的问题,最后debug的结果发现并不是auto commit的问题,而是对于thread synchronization的问题处理不得当所导致的。
4。“手动地为每一个更新都编写一个恢复原始数据的方法”是错误的。试想想,如果在你手动恢复数据的过程中又出现了Exception,你又如何保证data consistency呢?
5。自己编写TransactionManager是一件比较复杂的工作,不是我想建议的。这也是为什么banq强烈推荐EJB的原因。EJB提供了TransactionManager的功能,我们可以采用EJB的解决方案,just off-the-shelf,不是吗?或者用JTA和DataSource一道实现Transaction的control。
6。如果你必须要采用自己编写的TransactionManager,我可以讲解一下J2EE CONTAINER所提供的JTA/JTS的实现原理,或许对于你编写自己的TransactionManager有一定的帮助。
7。我们知道在J2EE Spec中提供了UserTransaction和DataSource的interface的定义,具体是如何实现的留给那些J2EE Container的vendor来实现,对于application developer来说他所能见到的就是这两个interface。对于支撑这两个interface背后的东西,application developer是永远都不可能知道的。看看下面的architecture吧
User-defined Application API
----------------------------
UserTransaction DataSource
----------------------------
DBConnectionPool ThreadConnectionMap
(XAConnection, XAResource, XADataSource)
我们清楚的看到,对于UserTransaction,DataSource的支持离不开我们所看不到的J2EE spec中的一些定义,对于application developer来说,它隐藏了这些东西的复杂性。与application developer打交道的只是UserTransaction和DataSource。
================
sample code
public class JTATest
{
public JTATest()
{
}
public static void main(String[] args)
{
DataSource ds = null;
Context ctx = null;
Connection myConn = null;
UserTransaction tx = null;
try
{
ctx = getInitialContext();
tx = (UserTransaction)
ctx.lookup("javax.transaction.UserTransaction");
tx.begin();
ds = (javax.sql.DataSource)
ctx.lookup ("mysqlDS");
}
catch (Exception E)
{
System.out.println("Init Error: " + E);
}
Statement myStatement = null;
ResultSet myResultSet = null;
try
{
myConn = ds.getConnection();
myStatement = myConn.createStatement();
myStatement.executeUpdate ("INSERT INTO emp (empname,empid,job) VALUES ('John', 10 ,'sales')");
tx.commit();
System.out.println("Success!");
}
catch (Exception e)
{
try
{
tx.rollback();
}
catch(Exception e1)
{
}
System.out.println("Error message = " + e.getMessage());
}
finally
{
try
{
if (myStatement != null)
{
myStatement.close();
}
if (myConn != null)
{
myConn.close();
}
}
catch (SQLException e)
{
System.out.println("Error code = " + e.getErrorCode());
System.out.println("Error message = " + e.getMessage());
}
}
}
private static Context getInitialContext() throws Exception
{
String url = "t3://localhost:7001";
String user = "weblogic";
String password = "zhangjane";
Properties properties = null;
try
{
properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, url);
if (user != null)
{
properties.put(Context.SECURITY_PRINCIPAL, user);
properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);
}
return new InitialContext(properties);
}
catch(Exception e)
{
throw e;
}
}
}
------------------------------------------
con.setAutoCommit(false); //关闭自动Commit
PreparedStatement updateSales = con.prepareStatement(
"UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?");
updateSales.setInt(1, 50);
updateSales.setString(2, "Colombian");
updateSales.executeUpdate();//执行Update Sales操作
PreparedStatement updateTotal = con.prepareStatement(
"UPDATE COFFEES SET TOTAL = TOTAL + ? WHERE COF_NAME LIKE ?");
updateTotal.setInt(1, 50);
updateTotal.setString(2, "Colombian");
updateTotal.executeUpdate();//执行Update Total操作, 注意, 此二者必须同时执行成功 或同时失败.
con.commit(); //commit以上两个操作, 同时成功或失败
con.setAutoCommit(true); //将AutoCommit恢复为true
分享到:
相关推荐
1、写在开头 标题之前我想说一下Linux的mysql真的实在是太坑了。太坑了。总是会出现这样那样的你想不到的问题。崩溃了。首先来罗列一下我遇到过的...Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorExcepti
在JDBC中,事务(Transaction)管理是确保数据一致性、完整性和并发控制的关键部分。 1. **JDBC连接池配置** - **配置连接池**:在WebLogic等应用服务器中,JDBC连接池用于管理数据库连接,以提高效率和资源利用率...
本文旨在深入探讨Hibernate事务管理机制,特别是JDBC Transaction与JTA Transaction在Hibernate中的实现方式及其区别。 #### 二、Hibernate事务管理配置 在使用Hibernate进行开发时,可以通过配置`hibernate....
典型的J2EE三层结构,分为表现层... Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,
在 Hibernate 中,事务管理可以基于 JDBC Transaction 或 JTA (Java Transaction API) 进行,这两种方式各有特点。 首先,Hibernate 默认的事务处理机制是基于 JDBC Transaction。这意味着在进行数据库操作时,...
在 JdbcTransaction 类中,事务的开始、提交和回滚实际上对应于 `conn.setAutoCommit(false)`、`conn.commit()` 和 `conn.rollback()`。`close()` 方法并不真正关闭事务,而是将连接返回到连接池中。这里值得注意的...
│ │ │ frame-sourcefiles-org.apache.ibatis.logging.jdbc.html │ │ │ frame-sourcefiles-org.apache.ibatis.logging.jdk14.html │ │ │ frame-sourcefiles-org.apache.ibatis.logging.log4j.html │ │ │ ...
org.hibernate.TransactionException: JDBC rollback failed
3. **`createTransaction()`** 方法由`SessionFactory`的`TransactionFactory`实现,它负责创建具体的`Transaction`实现对象,通常是`JDBCTransaction`。 4. **`JDBCTransaction`** 类的`begin()`方法用于真正启动...
MyBatis 会创建 `JdbcTransactionFactory` 实例,该工厂会创建 `JdbcTransaction` 对象,这个对象负责执行 JDBC 的事务操作。 2. **MANAGED 事务管理**:在这种模式下,MyBatis 不直接管理事务,而是依赖于应用...
源码中的`ManagedTransaction`和`JdbcTransaction`分别对应容器管理和手动管理两种模式。 6. 注解支持:MyBatis3引入了注解支持,使得在不写XML配置的情况下也能完成映射。`AnnotationBeanParser`类解析注解并生成...
MyBatis的事务管理涉及到Transaction接口和其实现类,如JdbcTransaction,它们协同工作以处理事务的生命周期。 通过以上讲解,我们可以看到MyBatis的事务管理机制不仅提供了灵活性,也确保了数据的完整性和一致性。...
5. **事务(Transaction)管理**:JDBC支持ACID(原子性、一致性、隔离性和持久性)事务属性,确保数据的完整性和一致性。`Connection`对象提供了开始、提交和回滚事务的方法。 6. **批处理(Batch Processing)**...
在源码中,`org.apache.ibatis.transaction.jdbc.JdbcTransaction`和`org.apache.ibatis.transaction.managed.ManagedTransaction`分别对应JDBC和Spring的事务管理。 十、缓存机制 iBatis提供了本地缓存和二级缓存...
7. Transaction管理:`Transaction`接口定义了事务操作,其底层实现了JDBC的事务管理,如`JdbcTransaction`。 四、源码学习价值 深入研究Hibernate 4.1.5源码,不仅可以理解ORM框架的基本工作原理,还可以了解到...
1. **JDBCTransaction**:基于JDBC的本地事务。 2. **JTATransaction**:支持分布式事务。 3. **Sessioncontext和事务边界**:定义事务范围。 4. **Thread**:线程安全的事务管理。 5. **OpenSessionInView**:解决...
5. **事务处理**:Hibernate支持JTA(Java Transaction API)和JTAS(JDBC Transaction API),通过Session的beginTransaction和commit/rollback方法管理事务。 6. **缓存机制**:一级缓存是Session级别的,自动...
本文将深入探讨在Eclipse环境中使用Hibernate开发应用程序时涉及到的Transaction管理,特别是JDBC Transaction和JTA(Java Transaction API)Transaction的区别与使用。 首先,Hibernate并不直接提供事务处理功能,...
在源代码中,`org.hibernate.Transaction`的实现类如`JDBCTransaction`处理了数据库事务的开始、提交和回滚。 3. **查询语言(HQL)和Criteria API** Hibernate 提供了自己的SQL方言——HQL(Hibernate Query ...