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
典型的J2EE三层结构,分为表现层... Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,
来自Bea权威的内容,能够从中学到JDBC的理论知识,解决你长期混淆不清的概念,促进你更好进行JDBC开发
各种jar 包含webservice 等等
│ │ │ 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
com.huawei.gauss.jdbc.ZenithDriver.jar包是华为自验数据库GaussDb 100的驱动,如果要通过数据库客户端连接GaussDb数据库,就要添加此驱动,可以通过DBerver客户端连接GaussDB数据库。
1.事务(Transaction)的概念 2.MySQL数据库中操作事务命令 2.1.编写测试SQL脚本,如下: 2.2.开启事务(start transaction) 2.3.提交事务(commit) 2.4回滚事务(rollback) 3.JDBC中使用事务 3.1....
对于Transaction 管理 为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。
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 ...
Hibernate本身是不具备Transaction处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,下面我们详细的分析: Hibernate可以配置为JDBCTransaction或者是JTA...
JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。本文的目的是要提供一个关于的Java事务处理API(JTA)...
Java JTA 与 JDBC 类似,也是 Java 中的一种规范,JDBC 定义了 Java 应用程序如何访问数据库,而 JTA 则定义 Java 应用程序如何实现分布式事务。 Java 中与数据库相关的技术还包括 JPA,它们都分别提供了一套事务 ...
WebLogic JDBC & Transaction版精华帖整理 崔飞飞 (DEV2DEV ID:CONVERSE) 关于WebLogic JDBC的基本配置知识,连接池使用,事务处理,以及常见问题的解答。
bach, scroll, transaction, DML, preparedStatemnet
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 ...
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的API (熟记于心) 三.JDBC应用步骤(熟记于心) 四.元数据(了解) ...事务(Transaction)(熟记于心) 六.JDBC2.0新特性(了解) 其中批处理必须掌握。
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a ...
注:本文是斑竹从JDBC & Transaction版摘录广大站友的提问以及各种解答整理而来,如果您认为本文的内容已触犯了您的权益,请联系管理员进行修改。 Jbuilder正确连接 oracle 9i需要注意的几个问题 oracle8以上的应该...