sql >> Databasteknik >  >> RDS >> Mysql

Varför ignorerar Rails en återställning i en (pseudo)kapslad transaktion?

Egentligen är det exakt så här kapslade transaktioner designades för. Jag citerar från oracle docs:

Alltså en underordnad transaktion i en vanlig kapslad transaktion har inget att säga till om hur han eller de andra barnen eller föräldern (större transaktion). ) kan fungera, annat än att ändra ömsesidig data eller misslyckas med ett undantag.

Men du kan bevilja honom (underordnad transaktion ) en mycket begränsad chans att rösta om sitt öde genom att använda sub-transaction funktion som anges på rails dokument genom att skicka requires_new: true

User.transaction do
  User.create(username: 'Kotori')
  User.transaction(requires_new: true) do
    User.create(username: 'Nemu')
    raise ActiveRecord::Rollback
  end
end

Vilket som doktorerna säger:skapar bara 'Kotori'. sedan det mäktiga "Nemu"-barnet valde att dö tyst.

Mer information om inkapslade transaktionsregler (oracle docs )

Uppdatering:

För att bättre förstå varför rails nested transactions fungerar på det här sättet, du behöver veta lite mer om hur kapslade transaktioner fungerar på DB-nivå, jag citerar från rails api-dokument :

Ok, då beskriver dokumenten beteendet hos en nested transaction i de två nämnda fallen enligt följande:

I händelse av ett kapslat anrop, #transaction kommer att bete sig enligt följande:

  • Blocket kommer att köras utan att göra något. Alla databassatser som sker inom blocket läggs effektivt till den redan öppna databastransaktionen.

  • Men om :requires_new är inställt kommer blocket att lindas in i en databassparpunkt som fungerar som en undertransaktion.

Jag föreställer mig försiktig, bara föreställ mig det:

alternativ(1) (utan requires_new) finns där om du använde ett DBMS som fullt ut stöder nested transactions eller så är du nöjd med det "falska" beteendet hos nested_attributes

medan alternativ(2) är att stödja savepoint lösning om du inte gör det.



  1. MySQL:Ta bort alla rader äldre än 10 minuter

  2. rake db:create throws databas finns inte fel med postgresql

  3. MySQL-fel:Du har ett fel i din SQL-syntax; kontrollera manualen som motsvarar din MySQL-serverversion för rätt syntax att använda nära

  4. mysql datetime jämförelse