在插入主订单之后再调用插入子订单方法时可能发生异常,此时应该在方法中用throws直接抛出SQLExeception异常,而不是用trycatch来捕获,如果用try-catch捕获出现异常不能正常被捕获到。贴代码来看。
以下是插入主订单数据到DB中,其中调用了插入子订单到数据库的方法。
@Override
public int addOrderTODB(CommodityCar commodityCar) {
// TODO Auto-generated method stub
//主订单的编号
int oNo = 0;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
String sqlString = "INSERT INTO mainorder(opost,ophone,oextra,oprice,opeople,oaddress,uid) values(?,?,?,?,?,?,?)";
DBConn dbConn = new DBConn();
connection = dbConn.getConn();
try {
//设置为手动提交事务
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(sqlString);
//要插入9个数据,opost,ophone,oextra,oprice,opeople,oaddress,uid,sno
preparedStatement.setString(1, commodityCar.getOpost());
preparedStatement.setString(2, commodityCar.getOphone());
preparedStatement.setString(3, commodityCar.getOextra());
preparedStatement.setFloat(4, commodityCar.getOprice());
preparedStatement.setString(5, commodityCar.getOpeople());
preparedStatement.setString(6, commodityCar.getOaddress());
preparedStatement.setInt(7, commodityCar.getUid());
preparedStatement.executeUpdate();
//再插入子订单信息,子订单对主订单关系为多对一
preparedStatement = connection.prepareStatement("select @@IDENTITY id from mainorder");
rs = preparedStatement.executeQuery();
if(rs.next())
{
oNo = rs.getInt("id");
}
for(CommoditySingle commoditySingle:commodityCar.getCommoditySingles())
{
childOrderImpl.addChildorderTODB(oNo, commoditySingle, connection);
}
//将事务提交
connection.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
//如果捕获到异常,应该进行事务回滚
connection.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//返回订单编号,用于后面支付页面显示
return oNo;
}
插入子订单的方法:
@Override
public void addChildorderTODB(int oNo, CommoditySingle commoditySingle,Connection connection) throws SQLException {
// TODO Auto-generated method stub
PreparedStatement preparedStatement = null;
String sqlChild = "INSERT INTO childorder(cname,cprice,cquantity,oNo,cono) values(?,?,?,?,?)";
preparedStatement = connection.prepareStatement(sqlChild);
preparedStatement.setString(1, commoditySingle.getCname());
preparedStatement.setFloat(2, commoditySingle.getCprice());
preparedStatement.setInt(3, commoditySingle.getCquantity());
preparedStatement.setInt(4, oNo);
preparedStatement.setInt(5, commoditySingle.getCono());
preparedStatement.executeUpdate();
}
此处可以看到我是在方法中直接用throws SQLException,这种办法可以正确抛出异常,并回滚插入主订单和子订单事务。但是如果用try-catch(如下)
<pre class="java" name="code"> @Override
public void addChildorderTODB(int oNo, CommoditySingle commoditySingle,Connection connection) {
// TODO Auto-generated method stub
PreparedStatement preparedStatement = null;
String sqlChild = "INSERT INTO childorder(cname,cprice,cquantity,oNo,cono) values(?,?,?,?,?)";
try{
preparedStatement = connection.prepareStatement(sqlChild);
preparedStatement.setString(1, commoditySingle.getCname());
preparedStatement.setFloat(2, commoditySingle.getCprice());
preparedStatement.setInt(3, commoditySingle.getCquantity());
preparedStatement.setInt(4, oNo);
preparedStatement.setInt(5, commoditySingle.getCono());
preparedStatement.executeUpdate();
}catch(Exeception e)
{
e.printstackTrace();
}
}
则不能在调用方法的那里正确回滚,会出现插入主订单却没有插入子订单的情况。