转账时必须双方同时成功,要么同时失败,就是把双方组成单元放到事务中
1)显示的开启一个事务:start transaction
2)事务提交:commit代表从开启事务到事务提交 中间的所有的sql都认为有效 真正的更新数据库
3)事务的回滚:rollback 代表事务的回滚 从开启事务到事务回滚 中间的所有的 sql操作都认为无效数据库没有被更新
一、JDBC事务操作
默认是自动事务:
执行sql语句:executeUpdate() ---- 每执行一次executeUpdate方法 代表 事务自动提交
通过jdbc的API手动事务:
开启事务:conn.setAutoComnmit(false);
提交事务:conn.commit();
回滚事务:conn.rollback();
注意:控制事务的connnection必须是同一个
执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制
一、事务的特性和隔离级别(概念性问题---面试)
事务的特性ACID
? 1)原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作 要么都发生,要么都不发生。
? 2)一致性(Consistency)一个事务中,事务前后数据的完整性必须保持一致。
? 3)隔离性(Isolation)多个事务,事务的隔离性是指多个用户并发访问数据库时, 一个用户的 事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
? 4)持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变 就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
转账功能
//jsp
<form action="${pageContext.request.contextPath }/ZhuanzhangServlet" method="post">
转入账户<input type="text" name="in"><br>
转除账户<input type="text" name="out"><br>
金额<input type="text" name="money"><br>
<input type="submit" name="转账">
</form>
public class ZhuanzhangServlet extends HttpServlet {
private AccService accService=new AccService();
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
//获取三个参数
String out=request.getParameter("out");
String in=request.getParameter("in");
String moneyStr=request.getParameter("money");
double money=Double.parseDouble(moneyStr);//字符串转Double
int row=accService.transfer(out, money, in);
//解决响应
response.setContentType("text/html;charset=UTF-8");
if(row>0){
response.getWriter().write("转账成功");
}else{
response.getWriter().write("转账失败");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
public class AccDao {
//转出
public int outMoney(Connection conn,String out,double money) throws SQLException{
QueryRunner qr=new QueryRunner();
String sql="update account set money=money-? where name=?";
int row=qr.update(conn,sql,money,out);
return row;
}
public int inMoney(Connection conn,String in,double money) throws SQLException{
QueryRunner qr=new QueryRunner();
String sql="update account set money=money+? where name=?";
int row=qr.update(conn,sql,money,in);
return row;
}
}
public class AccService {
private AccDao accDao=new AccDao();
//转出(转账方法)
public int transfer(String out,double money,String in){
int row=0;
int row1=0;
Connection conn=null;
try {
//获取连接对象
conn=MyDBUtils.getConn();
//开启事务
conn.setAutoCommit(false);
row=accDao.outMoney(conn,out, money);
int y=1/0;
row1=accDao.inMoney(conn,in, money);
} catch (Exception e) {
//回滚
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
} finally{
try {
//提交事务
conn.commit();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(row>0&&row1>0){
return 1;
}else{
return 0;
}
}
}
