jfinal 1.8 事务不生效问题。

本次使用事务方式:
Db.tx(new IAtom() {
				public boolean run() throws SQLException {
					try {
						//用户基本信息
						User.dao.insertInfo(basicInfoMap);
						//其他信息
						Ohter.dao.insertInfo(otherMapList);
					} catch (Exception e) {
						throw new SQLException("写入信息失败,失败信息!");
					}
					// 此返回结果  自行判断处理
					return true;
				}
			});

断点查看没有进行自动提交;

/**
	 * Execute transaction.
	 * @param config the Config object
	 * @param transactionLevel the transaction level
	 * @param atom the atom operation
	 * @return true if transaction executing succeed otherwise false
	 */
	boolean tx(Config config, int transactionLevel, IAtom atom) {
		Connection conn = config.getThreadLocalConnection();
		if (conn != null) {	// Nested transaction support
			try {
				if (conn.getTransactionIsolation() < transactionLevel)
					conn.setTransactionIsolation(transactionLevel);
				boolean result = atom.run();
				if (result)
					return true;
				throw new NestedTransactionHelpException("Notice the outer transaction that the nested transaction return false");	// important:can not return false
			}
			catch (SQLException e) {
				throw new ActiveRecordException(e);
			}
		}
		
		Boolean autoCommit = null;
		try {
			conn = config.getConnection();
			autoCommit = conn.getAutoCommit();
			config.setThreadLocalConnection(conn);
			conn.setTransactionIsolation(transactionLevel);
			conn.setAutoCommit(false);
			boolean result = atom.run();
			//该处断点  没有进行提交 但是数据已经插入。
			//数据库也测试了一下 支持事务提交
			if (result)
				conn.commit();
			else
				conn.rollback();
			return result;
		} catch (NestedTransactionHelpException e) {
			if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
			return false;
		} catch (Exception e) {
			if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
			throw e instanceof RuntimeException ? (RuntimeException)e : new ActiveRecordException(e);
		} finally {
			try {
				if (conn != null) {
					if (autoCommit != null)
						conn.setAutoCommit(autoCommit);
					conn.close();
				}
			} catch (Exception e) {
				e.printStackTrace();	// can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
			} finally {
				config.removeThreadLocalConnection();	// prevent memory leak
			}
		}
	}

于是跟踪每一个SQL语句执行:

//其他信息
Ohter.dao.insertInfo(otherMapList);

内部代码:

Db.batch(sqlList, sqlList.size());
	private int[] batch(Config config, Connection conn, List<String> sqlList, int batchSize) throws SQLException {
		if (sqlList == null || sqlList.size() == 0)
			throw new IllegalArgumentException("The sqlList length must more than 0.");
		if (batchSize < 1)
			throw new IllegalArgumentException("The batchSize must more than 0.");
		int counter = 0;
		int pointer = 0;
		int size = sqlList.size();
		int[] result = new int[size];
		Statement st = conn.createStatement();
		for (int i=0; i<size; i++) {
			st.addBatch(sqlList.get(i));
			if (++counter >= batchSize) {
				counter = 0;
				int[] r = st.executeBatch();
				//此处进行了 提交,所以导致了外部事务 看似没有生效的问题。。。。
                //解决方案就要看,具体业务了,重写批量还是循环处理。。。
				conn.commit();
				for (int k=0; k<r.length; k++)
					result[pointer++] = r[k];
			}
		}
		int[] r = st.executeBatch();
		conn.commit();
		for (int k=0; k<r.length; k++)
			result[pointer++] = r[k];
		DbKit.closeQuietly(st);
		return result;
	}


事务如果无效,1:查看事务是否执行。2:查看数据库表的类型是否支持事务。3:是否有自动提交的SQL封装方法调用。

猜你喜欢

转载自blog.csdn.net/a290450134/article/details/80701060
1.8