`
abalone
  • 浏览: 130739 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

jdbc transaction

阅读更多
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 
分享到:
评论

相关推荐

    Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: ….. this is incompatible with sq

    1、写在开头 标题之前我想说一下Linux的mysql真的实在是太坑了。太坑了。总是会出现这样那样的你想不到的问题。崩溃了。首先来罗列一下我遇到过的...Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorExcepti

    JDBC & Transaction 总结整理

    在JDBC中,事务(Transaction)管理是确保数据一致性、完整性和并发控制的关键部分。 1. **JDBC连接池配置** - **配置连接池**:在WebLogic等应用服务器中,JDBC连接池用于管理数据库连接,以提高效率和资源利用率...

    Hibernate入门

    本文旨在深入探讨Hibernate事务管理机制,特别是JDBC Transaction与JTA Transaction在Hibernate中的实现方式及其区别。 #### 二、Hibernate事务管理配置 在使用Hibernate进行开发时,可以通过配置`hibernate....

    SSH框架优点及事务说明

    典型的J2EE三层结构,分为表现层... Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,

    Hibernate事务

    在 Hibernate 中,事务管理可以基于 JDBC Transaction 或 JTA (Java Transaction API) 进行,这两种方式各有特点。 首先,Hibernate 默认的事务处理机制是基于 JDBC Transaction。这意味着在进行数据库操作时,...

    MyBatis 事务管理解析:颠覆你心中对事务的理解!.docx

    在 JdbcTransaction 类中,事务的开始、提交和回滚实际上对应于 `conn.setAutoCommit(false)`、`conn.commit()` 和 `conn.rollback()`。`close()` 方法并不真正关闭事务,而是将连接返回到连接池中。这里值得注意的...

    前端-后端java的Util类的工具类

    │ │ │ frame-sourcefiles-org.apache.ibatis.logging.jdbc.html │ │ │ frame-sourcefiles-org.apache.ibatis.logging.jdk14.html │ │ │ frame-sourcefiles-org.apache.ibatis.logging.log4j.html │ │ │ ...

    ERRORLOG

    org.hibernate.TransactionException: JDBC rollback failed

    HibernateTemplate类的使用

    3. **`createTransaction()`** 方法由`SessionFactory`的`TransactionFactory`实现,它负责创建具体的`Transaction`实现对象,通常是`JDBCTransaction`。 4. **`JDBCTransaction`** 类的`begin()`方法用于真正启动...

    J2EE企业级项目开发-3期(KC007) 6.5 MyBatis的事务管理和缓存机制文档.doc

    MyBatis 会创建 `JdbcTransactionFactory` 实例,该工厂会创建 `JdbcTransaction` 对象,这个对象负责执行 JDBC 的事务操作。 2. **MANAGED 事务管理**:在这种模式下,MyBatis 不直接管理事务,而是依赖于应用...

    mybatis源码.rar

    源码中的`ManagedTransaction`和`JdbcTransaction`分别对应容器管理和手动管理两种模式。 6. 注解支持:MyBatis3引入了注解支持,使得在不写XML配置的情况下也能完成映射。`AnnotationBeanParser`类解析注解并生成...

    myBatis系列之七:事务管理

    MyBatis的事务管理涉及到Transaction接口和其实现类,如JdbcTransaction,它们协同工作以处理事务的生命周期。 通过以上讲解,我们可以看到MyBatis的事务管理机制不仅提供了灵活性,也确保了数据的完整性和一致性。...

    jdbc jdbc jdbc

    5. **事务(Transaction)管理**:JDBC支持ACID(原子性、一致性、隔离性和持久性)事务属性,确保数据的完整性和一致性。`Connection`对象提供了开始、提交和回滚事务的方法。 6. **批处理(Batch Processing)**...

    ibatis源码,ibatis源码 ibatis源码 ibatis源码

    在源码中,`org.apache.ibatis.transaction.jdbc.JdbcTransaction`和`org.apache.ibatis.transaction.managed.ManagedTransaction`分别对应JDBC和Spring的事务管理。 十、缓存机制 iBatis提供了本地缓存和二级缓存...

    hibernate 4.1.5 source code

    7. Transaction管理:`Transaction`接口定义了事务操作,其底层实现了JDBC的事务管理,如`JdbcTransaction`。 四、源码学习价值 深入研究Hibernate 4.1.5源码,不仅可以理解ORM框架的基本工作原理,还可以了解到...

    Hibernate学习笔记

    1. **JDBCTransaction**:基于JDBC的本地事务。 2. **JTATransaction**:支持分布式事务。 3. **Sessioncontext和事务边界**:定义事务范围。 4. **Thread**:线程安全的事务管理。 5. **OpenSessionInView**:解决...

    Hibernate实现原理模拟

    5. **事务处理**:Hibernate支持JTA(Java Transaction API)和JTAS(JDBC Transaction API),通过Session的beginTransaction和commit/rollback方法管理事务。 6. **缓存机制**:一级缓存是Session级别的,自动...

    Eclipse开发Hibernate应用程序

    本文将深入探讨在Eclipse环境中使用Hibernate开发应用程序时涉及到的Transaction管理,特别是JDBC Transaction和JTA(Java Transaction API)Transaction的区别与使用。 首先,Hibernate并不直接提供事务处理功能,...

    hibernater 源代码

    在源代码中,`org.hibernate.Transaction`的实现类如`JDBCTransaction`处理了数据库事务的开始、提交和回滚。 3. **查询语言(HQL)和Criteria API** Hibernate 提供了自己的SQL方言——HQL(Hibernate Query ...

Global site tag (gtag.js) - Google Analytics