我们以一个交易的事例来说明如何在mango框架中使用事务。
首先我们需要一张账户表来存储用户的账户数据,其中:uid是表账户标识,money则是账户余额:
DROP TABLE IF EXISTS `accounts`;
CREATE TABLE `accounts` (
`uid` int(11) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8接着书写AccountsDao:
@DB
public interface AccountsDao {
@SQL("update accounts set money = money + :2 where uid = :1")
boolean addMoney(int uid, int inc);
}下面是使用编程式事务的代码:
public class AccountsMain {
public static void main(String[] args) {
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mango_example";
String username = "root"; // 这里请使用您自己的用户名
String password = "root"; // 这里请使用您自己的密码
DataSource ds = new DriverManagerDataSource(driverClassName, url, username, password);
Mango mango = Mango.newInstance(ds);
AccountsDao dao = mango.create(AccountsDao.class);
int zhangsan = 1;
int lisi = 2;
int money = 100;
if (dao.getAccount(zhangsan) == null) {
dao.addAccount(zhangsan, 10000);
}
if (dao.getAccount(lisi) == null) {
dao.addAccount(lisi, 10000);
}
Transaction tx = TransactionFactory.newTransaction();
try {
dao.transferMoney(zhangsan, -money);
dao.transferMoney(lisi, money);
} catch (Throwable e) {
tx.rollback();
return;
}
tx.commit();
}
}上面的代码中zhangsan(张三)转给lisi(李四)100块。如果没有异常则事务提交,有异常则事务回滚。
在直接使用编程式事务时,由于编码较为复杂,容易出错。所以Mango框架提供了TransactionTemplate工具类,用于简化编程式事务的书写。
下面是使用TransactionTemplate的代码:
public class AccountsMain2 {
public static void main(String[] args) {
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mango_example";
String username = "root"; // 这里请使用您自己的用户名
String password = "root"; // 这里请使用您自己的密码
DataSource ds = new DriverManagerDataSource(driverClassName, url, username, password);
Mango mango = Mango.newInstance(ds);
final AccountsDao dao = mango.create(AccountsDao.class);
final int zhangsan = 1;
final int lisi = 2;
final int money = 100;
if (dao.getAccount(zhangsan) == null) {
dao.addAccount(zhangsan, 10000);
}
if (dao.getAccount(lisi) == null) {
dao.addAccount(lisi, 10000);
}
TransactionTemplate.execute(new TransactionAction() {
@Override
public void doInTransaction(TransactionStatus status) {
dao.transferMoney(zhangsan, -money);
dao.transferMoney(lisi, money);
}
});
}
}上面的代码中zhangsan(张三)转给lisi(李四)100块。如果没有异常则事务提交,有异常则事务回滚。
事务 的所有代码和表结构均可以在 mango-example 中找到。