`
abalone
  • 浏览: 127048 次
  • 性别: 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

    SSH框架优点及事务说明

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

    JDBC & Transaction 总结整理

    来自Bea权威的内容,能够从中学到JDBC的理论知识,解决你长期混淆不清的概念,促进你更好进行JDBC开发

    各种jar包

    各种jar 包含webservice 等等

    前端-后端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

    com.huawei.gauss.jdbc.ZenithDriver.jar

    com.huawei.gauss.jdbc.ZenithDriver.jar包是华为自验数据库GaussDb 100的驱动,如果要通过数据库客户端连接GaussDb数据库,就要添加此驱动,可以通过DBerver客户端连接GaussDB数据库。

    JDBC专题(五)-JDBC专题-JDBC事务.docx

    1.事务(Transaction)的概念 2.MySQL数据库中操作事务命令 2.1.编写测试SQL脚本,如下: 2.2.开启事务(start transaction) 2.3.提交事务(commit) 2.4回滚事务(rollback) 3.JDBC中使用事务 3.1....

    JDBC事务管理的简单实现

    对于Transaction 管理 为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。

    JDBC Developers Guide Reference.rar

    The Oracle JDBC Developers Guide and Reference contains 21 chapters and one appendix: Chapter 1, "Overview" This chapter provides an overview of the Oracle implementation of JDBC and the Oracle JDBC ...

    Eclipse开发Hibernate应用程序

    Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,下面我们详细的分析: Hibernate可以配置为JDBCTransaction或者是JTA...

    Java Transaction API概述

    JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。本文的目的是要提供一个关于的Java事务处理API(JTA)...

    Java Transaction API (JTA) Version 1.3 JSR-907

    Java JTA 与 JDBC 类似,也是 Java 中的一种规范,JDBC 定义了 Java 应用程序如何访问数据库,而 JTA 则定义 Java 应用程序如何实现分布式事务。 Java 中与数据库相关的技术还包括 JPA,它们都分别提供了一套事务 ...

    关于WebLogic JDBC的基本配置知识以及常见问题的解

    WebLogic JDBC & Transaction版精华帖整理 崔飞飞 (DEV2DEV ID:CONVERSE) 关于WebLogic JDBC的基本配置知识,连接池使用,事务处理,以及常见问题的解答。

    jdbc示例代码

    bach, scroll, transaction, DML, preparedStatemnet

    mysql jdbc 5.1.47

    Connector/J 5.0 支持MySQL 4.1、MySQL 5.0 servers、distributed transaction (XA)。 Connector/J 3.1 支持MySQL 4.1、MySQL 5.0 servers、MySQL 5.0 except distributed transaction (XA) support。 Connector/J ...

    mysqljdbc8.0.12

    Connector/J 5.0 支持MySQL 4.1、MySQL 5.0 servers、distributed transaction (XA)。 Connector/J 3.1 支持MySQL 4.1、MySQL 5.0 servers、MySQL 5.0 except distributed transaction (XA) support。 Connector/J ...

    JDBC---初学者入门

    一.JDBC原理概述(了解 能说出来就行) 二.JDBC的API (熟记于心) 三.JDBC应用步骤(熟记于心) 四.元数据(了解) ...事务(Transaction)(熟记于心) 六.JDBC2.0新特性(了解) 其中批处理必须掌握。

    dbcp 连接池不合理的锁导致连接耗尽解决方案

    org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a ...

    JDBC连接Oracle数据库常见问题及解决方法

    注:本文是斑竹从JDBC & Transaction版摘录广大站友的提问以及各种解答整理而来,如果您认为本文的内容已触犯了您的权益,请联系管理员进行修改。 Jbuilder正确连接 oracle 9i需要注意的几个问题 oracle8以上的应该...

Global site tag (gtag.js) - Google Analytics