当我发出"SaveChanges()"时,实体框架中的默认事务隔离级别是什么?我找不到任何地方.它应该是"可序列化的"吗?
只要事务尚未提交,SQL Server是否允许事务中的约束违规(即延迟约束)?
我有一个正在运行的未提交的事务,当这个事务正在运行时,我将更改我的数据,以便它会违反某些约束(例如,有重复的主键).当我提交事务时,数据将处于一致的有效状态.这通常是在SQL中,特别是在MS SQL Server中允许的吗?
我遇到了问题,我发现的所有文章或例子似乎都不关心它.
我想在事务中执行一些数据库操作.我想做的与大多数例子非常相似:
using (SqlConnection Conn = new SqlConnection(_ConnectionString))
{
try
{
Conn.Open();
SqlTransaction Trans = Conn.BeginTransaction();
using (SqlCommand Com = new SqlCommand(ComText, Conn))
{
/* DB work */
}
}
catch (Exception Ex)
{
Trans.Rollback();
return -1;
}
}
Run Code Online (Sandbox Code Playgroud)
但问题是SqlTransaction Trans在try块内声明了.所以它在catch()块中是不可访问的.大多数例子只是在阻止之前Conn.Open()和Conn.BeginTransaction()之前try,但我认为这有点风险,因为两者都可以抛出多个异常.
我错了,还是大多数人都忽略了这种风险?如果发生异常,什么是能够回滚的最佳解决方案?
我正在尝试更多地了解数据库事务,我发现ACID用于编写事务的经验法则和几个问题的思考.
ACID经验法则:
交易必须是:
- 原子 - 它是一个工作单元,不依赖于以前和以后的交易.
- 一致 - 数据被提交或回滚,没有"中间"的情况,其中某些东西已经更新,而某些东西没有.
- 隔离 - 没有事务看到当前事务的中间结果.
- 持久 - 即使系统在之后崩溃,如果数据已提交,则值仍然存在.
我想知道它们是如何工作的,所以我可以更好地理解在编写这样的交易时需要考虑的因素.我想具体细节会因可用的数据库实现而有所不同,但某些规则将始终存在.
我有一个InnoDB表需要每隔十分钟在60k到200k记录的任何地方重新填充.到目前为止,我们的方法如下:
执行截断操作后,数据会立即删除,并且不再可用于用户界面.对于我们的用户来说,这非常令人不安,即使在大约30秒左右的时间内脚本遇到了Commit操作并且表格被重新填充.
我想,也许我可以包住整个操作过程,包括了Truncate在一个事务,这可能削减的时间长度,在此期间表出现空给用户.所以我改变了SET AUTOCOMMIT=0对START TRANSCATION.
哎呀!这与预期的效果相反!现在TRUNCATE操作仍然发生在脚本的开头,但实际执行事务中的操作需要更长INSERT的时间,因此当COMMIT操作发生并且表中的数据再次可用时,它已经接近十分钟!
有什么可能导致这种情况?说实话,我根本没想到会有任何改变,因为我认为启动交易基本上只是关闭Autocommit了?
我正在使用Codeigniter交易
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->trans_complete();
Run Code Online (Sandbox Code Playgroud)
这工作得很好,我有问题是内部的trans_start和trans_complete我打电话等功能,这些功能与数据库交易,使他们包含插入和更新以及一些删除...例如:
$this->db->trans_start();
$this->utils->insert_function($data);
$this->utils->update_function2($test);
$this->db->trans_complete();
Run Code Online (Sandbox Code Playgroud)
现在,如果执行这些函数并且发生一些错误,CodeIgniter将不会执行回滚.
处理此类问题的最佳方法是什么?
我想到的唯一解决方案是从这些函数返回错误并在那些函数内添加(trans_stat和trans_complete)如果它返回错误测试则执行$this->db->trans_rollback
例如:
$this->db->trans_start();
$result = $this->utils->insert_function($data);
if($result === false){
$this->db->trans_rollback();
}
$this->db->trans_complete();
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?
更新1:
根据要求我正在调用的外部函数示例:
// insert_function contains
$rec = array(
'numero' => $numero,
'transaction_id' => $id,
'debit' => $product_taxes['amount_without_taxes'],
'date' => $data['date_transaction'],
);
$this->addExerciceAccountingRecords($rec);
and addExerciceAccountingRecords contains
function addExerciceAccountingRecords($records) {
$this->db->insert('transactions_exercices', $records);
}
Run Code Online (Sandbox Code Playgroud) 我有这种情况:
所以步骤1,2,3,4应该在一个交易中,或者步骤1,2,3,5
我的流程从这里开始(这是一个计划任务):
public class ReceiveMessagesJob implements ScheduledJob {
// ...
@Override
public void run() {
try {
processMessageMediator.processNextRegistrationMessage();
} catch (Exception e) {
e.printStackTrace();
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
我在ProcessMessageMediator中的主要功能(processNextRegistrationMessage):
public class ProcessMessageMediatorImpl implements ProcessMessageMediator {
// ...
@Override
@Transactional
public void processNextRegistrationMessage() throws ProcessIncomingMessageException {
String refrenceId = null;
MessageTypeEnum registrationMessageType = MessageTypeEnum.REGISTRATION;
try {
String messageContent = incomingMessageService.fetchNextMessageContent(registrationMessageType);
if (messageContent == null) {
return;
}
IncomingXmlModel …Run Code Online (Sandbox Code Playgroud) 去年夏天,我开发了一个基本的ASP.NET/SQL Server CRUD应用程序,单元测试是其中一个要求.当我尝试对数据库进行测试时遇到了一些麻烦.根据我的理解,单元测试应该是:
在开发数据库时,这些要求似乎彼此不一致.例如,我无法在不确定要插入的行的情况下测试Insert(),因此我需要先调用Delete().但是,如果他们还没有呢?然后我需要先调用Exists()函数.
我最终的解决方案涉及非常大的设置功能(yuck!)和一个空的测试用例,它将首先运行并指示设置运行没有问题.这是牺牲测试的独立性,同时保持他们的无国籍状态.
我找到的另一个解决方案是将函数调用包装在一个可以轻松回滚的事务中,比如Roy Osherove的XtUnit.这项工作,但它涉及另一个库,另一个依赖,并且对于手头的问题似乎有点太沉重的解决方案.
那么,在面对这种情况时,SO社区做了什么?
tgmdbm说:
您通常使用自己喜欢的自动单元测试框架来执行集成测试,这就是为什么有些人会感到困惑,但他们不遵循相同的规则.您可以参与许多课程的具体实施(因为它们已经过单元测试).您正在测试具体类如何与彼此以及与数据库交互.
因此,如果我正确地阅读此内容,则无法有效地对数据访问层进行单元测试.或者,数据访问层的"单元测试"是否涉及测试,例如,由类生成的SQL /命令,而不依赖于与数据库的实际交互?
我已经阅读了文档和解释为什么强烈建议在NH中使用读取操作的事务.但是,我还没有完全"买进"它.有人可以试着解释它而不只是告诉我RTFM,我已经做过了吗?;)
我一直在导入大量CSV数据文件; 通常少于100,000条记录.我正在使用PHP和MySQL(InnoDB表).我需要使用PHP来转换某些字段并在MySQL之前进行一些文本处理INSERT(process_note_data()下面代码的一部分).MySQL LOAD DATA是不可行的,所以请不要建议.
我最近尝试使用START TRANSACTION和使用MySQL事务来提高此过程的速度COMMIT.性能提升令人惊讶.处理时间减少了20倍.因此,20分钟的处理只需要大约1分钟.
质询.
1.)有谁理解为什么有这样的性能提升(20分钟到1分钟)?
2.)我应该关注10万条记录的交易量有多大?
3.)我是否应该关注交易中的大量插入和/或更新?
/*
* Customer Notes Data:
* Rows are either a meeting, call or note!
*/
$row = 1;
$data = array();
$fields = array();
$line = '';
$db->query('SET autocommit=0;');
$db->query('START TRANSACTION;');
if (($handle = fopen("modules/".$currentModule."/Data/customernote.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 4096, ',', '"')) !== FALSE && $row < 999000) {
//Row 1 - CSV header row with field …Run Code Online (Sandbox Code Playgroud) transactions ×10
mysql ×3
ado.net ×2
c# ×2
database ×2
php ×2
sql ×2
.net ×1
codeigniter ×1
constraints ×1
csv ×1
hibernate ×1
innodb ×1
java ×1
nhibernate ×1
rollback ×1
spring ×1
sql-server ×1
truncate ×1
unit-testing ×1
xtunit ×1