1. 事务管理
开发中,在业务层(Service)控制事务!!!
在jdbc中处理事务,都是通过Connection完成的, 同一事务中所有的操作,都在使用同一个Connection对象。
2. Connection接口中与事务相关的三个方法
-
setAutoCommit(boolean)
-
设置是否为自动提交事务
-
如果true(默认值就是true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务
-
如果设置false,那么就相当于开启了事务了
conn.setAutoCommit(false)表示开启事务;
-
-
commit()
- 提交结束事务,conn.commit()表示提交事务;
-
rollback()
- 回滚结束事务,conn.rollback()表示回滚事务;
3. JDBC处理事务的代码格式
Connection conn = JDBCUtil.getConnection();
try{
conn.setAutoCommit(false); //开启事务
//执行代码
conn.commit();//提交事务
}catch(Exception e){
conn.rollback();//回滚
}finally{
conn.setAutoCommit(true);
}
4. 代码实现
Connection conn = null;
PreparedStatement pstmt = null;
@Test
public void testTransaction() {
int deptNo = 30;
conn = ConnectionUtil.getConnection();//获取连接对象
try {
//设置事务的提交方式为手动提交事务
conn.setAutoCommit(false);
//SQL语句
String sql1 = "update Emp set deptNo = null where deptNo = ?";
String sql2 = "delete from Dept where deptNo = ?";
//分别执行事务
pstmt = conn.prepareStatement(sql1);
pstmt.setInt(1, deptNo);
pstmt.executeUpdate();
pstmt = conn.prepareStatement(sql2);
pstmt.setInt(1, deptNo);
pstmt.executeUpdate();
//提交事务
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5. 具体案例 – 转账
- DB
CREATE TABLE "SCOTT"."BANK" (
ID NUMBER NOT NULL PRIMARY KEY ,
NAME VARCHAR2(50 BYTE) NOT NULL ,
BALANCE FLOAT(126) NOT NULL
)
INSERT INTO "SCOTT"."BANK" VALUES ('1', 'Tom', '100.00000000000000');
INSERT INTO "SCOTT"."BANK" VALUES ('2', 'Jerry', '3000.0000000000000');
ALTER TABLE "SCOTT"."BANK" ADD CONSTRAINT "CK_BALANCE" CHECK (balance >= 0) NOT DEFERRABLE INITIALLY IMMEDIATE NORELY VALIDATE;
- service interface
/**
* 业务逻辑实现类
*/
public interface BankService {
/**
* 转账
*/
public void ZhuanZhang(int fromId,int toId,double money);
}
- service impl
/**
* 业务逻辑实现类
*/
public class BankServiceImpl implements BankService {
private BankDao dao = new BankDaoImpl();
@Override
public void ZhuanZhang(int fromId, int toId, double money) {
// 数据库连接对象
Connection conn = JdbcUtil.getConnection1();
System.out.println("service.impl.conn:"+conn);
try {
// 关闭自动提交:false
// 开启事务
conn.setAutoCommit(false);
// 具体的业务
dao.zhuanZhang(conn, fromId, -money);
dao.zhuanZhang(conn, toId, money);
// 提交事务
conn.commit();
} catch (SQLException e) {
try {
// 回滚事务
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if (null != conn)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- dao interface
/**
* 数据访问接口
* @author Administrator
*
*/
public interface BankDao {
/**
* 转账
* @param id 账号
* @param money 金额
* @throws SQLException
*/
public void zhuanZhang(Connection conn,int id,double money) throws SQLException;
}
- dao.impl
public class BankDaoImpl implements BankDao {
@Override
public void zhuanZhang(Connection conn, int id, double money) throws SQLException {
String sql = "update Bank set balance = balance + ? where Id = ? ";
// Connection conn = JdbcUtil.getConnection1();
System.out.println("dao.impl.conn:" + conn);
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setDouble(1, money);
pstmt.setInt(2, id);
pstmt.executeUpdate();
}
}