The data is inserted using LINQ to SQL, the id is generated but the database table is empty.
Using a stored procedure there is no problem. But inserting using linq the id is generated everytime but the table is empty.
The code is below:
Int32 t = 2;
using (EduDataClassesDataContext db =new EduDataClassesDataContext())
{
using (var scope = new TransactionScope())
{
db.Connection.ConnectionString = Common.EdukatingConnectionString;
UserLogin userlog = new UserLogin();
userlog.Username = userinfo.Username;
userlog.Password = userinfo.Password;
userlog.UserTypeId = t;
userlog.FullName = userinfo.FullName;
db.UserLogins.InsertOnSubmit(userlog);
db.SubmitChanges();
Int64 n = userlog.Id;
UserInformation userinfor = new UserInformation();
userinfor.FirstName = userinfo.FirstName;
userinfor.LastName = userinfo.LastName;
userinfor.MobileNum = userinfo.MobileNum;
userinfor.Email = userinfo.Email;
userinfor.Gender = userinfo.Gender;
userinfor.Address = userinfo.Address;
userinfor.UserLoginId = n;
userinfor.CreatedBy = n;
userinfor.OrganizationName = userinfo.OrganizationName;
userinfor.DateOfBirth = userinfo.DateOfBirth;
userinfor.CreatedDate = DateTime.Now;
db.UserInformations.InsertOnSubmit(userinfor);
db.SubmitChanges();
}
}
When you are using a TransactionScope, you need to call the Complete method in order to Commit the transaction in the DataBase.
using (var db = new EduDataClassesDataContext())
using (var scope = new TransactionScope())
{
...
db.UserInformations.InsertOnSubmit(userinfor);
db.SubmitChanges();
// The Complete method commits the transaction. If an exception has been thrown,
// Complete is not called and the transaction is rolled back.
scope.Complete();
}
Failing to call this method aborts the transaction, because the
transaction manager interprets this as a system failure, or exceptions
thrown within the scope of transaction.
Related
For example I am adding the peoples data to database per state (this is not what I am doing exactly but the model is same). We have list of states and each state has millions of people. So initially in code, I am saving the state to get the State ID and then use that ID to bulk insert peoples data.
If something goes wrong while adding the peoples data, let's say 20th million record threw some exception, is there a way to revert back the data already saved in both Peoples and State table?
Any suggestion is highly appreciated..
List <Peoples> PeopleList = new List<Peoples>();
int peopleCounter = 0;
foreach (var stateVal in States)
{
using (var context = new StateEntities())
{
State st = new State();
st.ID = stateVal.ID;
st.Name = stateVal.Name;
context.State.Add(st);
context.SaveChanges();
if (stateVal.Peoples != null )
{
foreach (var _p in stateVal.Peoples)
{
Peoples _people = new Peoples();
_people.Name = _p.Name;
_people.Age = _P.Age;
_people.State_ID = stateVal.ID; // Getting state ID from State object as it already saved to DB
PeopleList.Add(_people)
peopleCounter++;
if (peopleCounter == 100000)
{
InsertPeople(PeopleList, context); // does bulk insert when PeopleList reaches 100k
PeopleList.Clear();
peopleCounter = 0;
}
}
}
}
}
private static void InsertPeople(List<Peoples> PeopleList, StateEntities context)
{
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ValidateOnSaveEnabled = false;
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, new System.TimeSpan(0, 30, 0)))
{
context.BulkInsert(PeopleList, options => options.BatchTimeout = 0);
context.SaveChanges();
transactionScope.Complete();
}
}
You can use transaction of SQL to rollback. It's supported by EF.
using (var context = new SchoolContext())
{
using (DbContextTransaction transaction = context.Database.BeginTransaction())
{
try
{
//**TODO: Do your bulk insert codes here**
// Save changes data in context
context.SaveChanges();
// Commit changes
transaction.Commit();
}
catch (Exception ex)
{
// Rollback all changes
transaction.Rollback();
}
}
}
Ref: https://learn.microsoft.com/en-us/ef/core/saving/transactions
I'm currently trying to implement some End to End Tests (E2E) using TranactionScope and local file Database (mdf). funny is that the query is not being rolled back, so all my update/inserts are persisted. I dont understand what is done wrong
using (new TransactionScope())
{
var newItem1 = new SomeEntity { Id = 4, Remark = "Test 2" };
var newItem2 = new SomeEntity { Id = 5, Remark = "Test 2" };
var x = new List<SomeEntity> { newItem1, newItem2 };
_testTvp.SaveSomeEntities(x);
var result = _test.GetSomeEntity(4);
Assert.AreEqual(newItem1.Remark, result.Remark);
result = _test.GetSomeEntity(5);
Assert.AreEqual(newItem2.Remark, result.Remark);
}
My connection string is:
for more code, see here: enter link description here
Nothing is wrong. This is how TransactionScope works.
From MSDN
If no exception occurs within the transaction scope (that is, between
the initialization of the TransactionScope object and the calling of
its Dispose method), then the transaction in which the scope
participates is allowed to proceed. If an exception does occur within
the transaction scope, the transaction in which it participates will
be rolled back.
It rollbacks the transaction only if an exception occurs
Why don't you try this with
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (SqlTransaction sqlTrans = sqlConnection.BeginTransaction())
{
//put your code here
}
}
Use something like as depending on your stack you might have ambient transactions:
string connStr = "...; Enlist = false";
using (TransactionScope ts = new TransactionScope())
{
using (SqlConnection conn1 = new SqlConnection(connStr))
{
conn1.Open();
conn1.EnlistTransaction(Transaction.Current);
}
}
Under what circumstances is an SqlConnection automatically enlisted in an ambient TransactionScope Transaction?
Try this:
using (new scope = new TransactionScope())
{
var newItem1 = new SomeEntity { Id = 4, Remark = "Test 2" };
var newItem2 = new SomeEntity { Id = 5, Remark = "Test 2" };
var x = new List<SomeEntity> { newItem1, newItem2 };
_testTvp.SaveSomeEntities(x);
var result = _test.GetSomeEntity(4);
Assert.AreEqual(newItem1.Remark, result.Remark);
result = _test.GetSomeEntity(5);
Assert.AreEqual(newItem2.Remark, result.Remark);
//either of the two following:
Transaction.Current.Rollback();
scope.Dispose();
}
Well, I couldnt figure out what exactly is wrong. The possible solution to this is to delete inserted data. Not the best way, but much better one using DbTransaction.I will try to create some test with real sql server and see what is difference.
Currently playing around with Dapper I'm trying to insert values into the db as follows
using (var sqlCon = new SqlConnection(Context.ReturnDatabaseConnection()))
{
sqlCon.Open();
try
{
var emailExists = sqlCon.Query<UserProfile>(#"SELECT UserId FROM User_Profile WHERE EmailAddress = #EmailAddress",
new { EmailAddress = userRegister.EmailAddress.Trim() }).FirstOrDefault();
if (emailExists == null) // No profile exists with the email passed in, so insert the new user.
{
userProfile.UniqueId = Guid.NewGuid();
userProfile.Firstname = userRegister.Firstname;
userProfile.Surname = userRegister.Surname;
userProfile.EmailAddress = userRegister.EmailAddress;
userProfile.Username = CreateUsername(userRegister.Firstname);
userProfile.Password = EncryptPassword(userRegister.Password);
userProfile.AcceptedTerms = true;
userProfile.AcceptedTermsDate = System.DateTime.Now;
userProfile.AccountActive = true;
userProfile.CurrentlyOnline = true;
userProfile.ClosedAccountDate = null;
userProfile.JoinedDate = System.DateTime.Now;
userProfile.UserId = SqlMapperExtensions.Insert(sqlCon, userProfile); // Error on this line
Registration.SendWelcomeEmail(userRegister.EmailAddress, userRegister.Firstname); // Send welcome email to new user.
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
sqlCon.Close();
}
}
The error I get is
ExecuteNonQuery requires the command to have a transaction when the connection
assigned to the command is in a pending local transaction. The Transaction
property of the command has not been initialized.
I have googled this error, but I misunderstood the answers provided.
From the error message I assume that you have started a transaction that was neither committed nor rolled back. The real cause for this error message is elsewhere.
I suggest you to log requests in Context.ReturnDatabaseConnection() and trace what requests precede this error.
Also I advice you to look in your code for all transactions and check if they are correctly completed (commit/rollback).
I am using session.query,first time its return latest database records and we populate on grid after editing on fields we save on database and then we again execute this query then it is not getting the updated record from database. the fields has updated in database but not getting updated record.
My NHibernate query is given below
List<FiscalPeriod> lstPeriods = new List<FiscalPeriod>();
using (var tr = session.BeginTransaction())
{
try
{
List<TSCFiscalPeriod> lstFiscalPeriods = session.Query<TSCFiscalPeriod>().ToList();
if (lstFiscalPeriods != null && lstFiscalPeriods.Count > 0)
{
foreach (var period in lstFiscalPeriods)
{
FiscalPeriod objPeriod = new FiscalPeriod();
objPeriod.Period = period.Id.FPeriod;
objPeriod.Name = "Period " + objPeriod.Period;
objPeriod.CompanyID = period.Id.FCompanyID;
objPeriod.Year = period.Id.FFiscalYear;
objPeriod.Begin = period.FBeginDate;
objPeriod.End = period.FEndDate;
objPeriod.OpenAP = FOpenAP(period.FOpen);
objPeriod.OpenGL = FOpenGL(period.FOpen);
objPeriod.SCFiscalPeriod = period;
objPeriod.IsExisting = true;
lstPeriods.Add(objPeriod);
}
}
tr.Commit();
}
catch (Exception ex)
{
lstPeriods = null;
CusException cex = new CusException(ex);
cex.Write();
}
return lstPeriods;
}
Is there any refresh method or something i am doing wrong.
Any help will be appreciated.thanks
make sure you are using session.clear() or session.flush() after save the session.
Nhibernate session is a static initializer.
Sometimes session is not able to refresh values.
So You have to flush and clear the session
session.flush();
session.clear();
I am creating a mechanism to bulk-insert (import) a lot of new records into a ORACLE database. I am using multiple threads and dependent transactions:
Creation of threads:
const int ThreadCount = 4;
using (TransactionScope transaction = new TransactionScope())
{
List<Thread> threads = new List<Thread>(threadCount);
for (int i = 0; i < ThreadCount; i++)
{
Thread thread = new Thread(WorkerThread);
thread.Start(Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete));
threads.Add(thread);
}
threads.ForEach(thread => thread.Join());
transaction.Complete();
}
The method that does the actual work:
private void WorkerThread(object transaction)
{
using (DependentTransaction dTx = (DependentTransaction)transaction)
using (TransactionScope ts = new TransactionScope(dTx))
{
// The actual work, the inserts on the database, are executed here.
}
}
During this operation, I get an exception of type System.Data.OracleClient.OracleException with the message ORA-24757: duplicate transaction identifier.
What am I doing wrong? Am I implementing the dependent transaction the incorrect way? Is it incompatible with Oracle? If so, is there a workarround?
I don't know about why u get this exception but a work around might be:
const int ThreadCount = 4;
using (var connection = new OracleConnection(MyConnectionstring))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
List<Thread> threads = new List<Thread>(ThreadCount);
for (int i = 0; i < ThreadCount; i++)
{
Thread thread = new Thread(WorkerThread);
thread.Start(transaction);
threads.Add(thread);
}
threads.ForEach(thread => thread.Join());
transaction.Commit();
}
}
and the working class would look something like:
private void WorkerThread(object transaction)
{
OracleTransaction trans = (OracleTransaction) transaction;
using (OracleCommand command = trans.Connection.CreateCommand())
{
command.CommandText = "INSERT INTO mytable (x) values (1) ";
command.ExecuteNonQuery();
}
}