728x90

php 작업중 여러 테이블에 데이터를 insert 할때는 트랜지션을 걸고 모든 데이터가 완료 되었을때 commit 을하고 하나라도 오류가 있을 경우에는 rollback 작업을걸어 준다. 이때 insert 하고 난 데이터는 마지막에 commit 되기 때문에 excute 에서는 데이터 조회가 되지 못하는데 설정값을 트랜지션 시작 지점 위에 선언해 주면 excute 까지만 되어도 해당 데이터는 insert 된것으로 인지하고 select 문을 실행한다. 

 

$pdo->exec("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
try {
    // 데이터베이스 연결 설정
    $pdo = new PDO('mysql:host=localhost;dbname=your_database', 'username', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 트랜잭션 격리 수준 설정
    $pdo->exec("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

    // 트랜잭션 시작
    $pdo->beginTransaction();

    // 삽입할 데이터 배열
    $dataToInsert = [
        ['value1' => '데이터1', 'value2' => '데이터2'],
        ['value1' => '데이터3', 'value2' => '데이터4'],
        // 추가 데이터...
    ];

    // 데이터 삽입 및 체크
    foreach ($dataToInsert as $data) {
        // 데이터 삽입
        $stmt = $pdo->prepare("INSERT INTO your_table (column1, column2) VALUES (:value1, :value2)");
        $stmt->execute([':value1' => $data['value1'], ':value2' => $data['value2']]);

        // 삽입된 데이터 체크
        $lastId = $pdo->lastInsertId();
        $checkStmt = $pdo->prepare("SELECT * FROM your_table WHERE id = :id");
        $checkStmt->execute([':id' => $lastId]);
        $result = $checkStmt->fetch();

        if (!$result) {
            // 데이터가 존재하지 않으면 롤백하고 종료
            $pdo->rollBack();
            echo "데이터 삽입에 실패했습니다: " . $data['value1'];
            exit;
        }
    }

    // 모든 데이터가 정상적으로 삽입되면 커밋
    $pdo->commit();
    echo "모든 데이터가 성공적으로 삽입되었습니다.";

} catch (Exception $e) {
    // 예외 처리
    $pdo->rollBack();
    echo "오류 발생: " . $e->getMessage();
}
 

 

 

트랜지션에는 4가지 종류가 있는데 각 상황에 맞게 시작지점에 선언해 주면 된다.

 

 

READ UNCOMMITTED: 다른 트랜잭션이 커밋하지 않은 변경 사항을 읽을 수 있습니다. (Dirty Reads 가능)
READ COMMITTED: 다른 트랜잭션이 커밋한 변경 사항만 읽을 수 있습니다. (Dirty Reads 방지)
REPEATABLE READ: 트랜잭션 시작 시점의 데이터를 읽습니다. (Phantom Reads 방지)
SERIALIZABLE: 가장 높은 격리 수준으로, 트랜잭션이 직렬화된 것처럼 동작합니다. (Phantom Reads 및 모든 충돌 방지)

 

한참 찾았는데 실제로 내가 해봤을때 되는 코드는 READ UNCOMMITTED 설정이니 참고 하면 좋겠다.

728x90
728x90

scss sass 등 css 스타일을 간단하게 사용 할수 있는 코드를 사용 하려면 react 나 vue 에서는 설치만 하면 바로 사용이 가능하지만 php 에서는 css 파일로 컴파일을 해줘야 한다.

vscode 에서 작업 중 이라면 Live sass Compiler 플러그인을 설치하면 저장할때 자동 컴파일 설정을 해두면 자동으로 컴파일이 되고 css 파일도 생성이 된다. 

 

 

이때 별도로 설정을 하지 않는다면 scss 파일이 있는 폴더 내에 동일한 이름으로 생성이 되는데 css 폴더만 별도로 분리해서 관리 하고 싶다면 설정을 아래와 같이 주면 된다. 

 

savePath 에 경로를 설정해주고 한참 찾았는데 "liveSassCompile.settings.autoprefix"  이 부분도 빈 배열로 넣어 주어야 아이폰등에서 적용 되는 코드가 같이 생성이 된다. 이 값이 없을 경우는 아이폰 파이어폭스 등에서만 적용이 되는 코드는 생성이 되지 않는다. 요즘 버전 업이 많이 되어서 그거 불필요한 코드 이긴 하지만 다양하 브라우저에서 대응하게 하고 싶다면 위 설정도 넣어 주는것이 좋다. 

 

    "git.enableSmartCommit": true,
    "editor.formatOnSave": true,
    "liveSassCompile.settings.formats": [
        {
            "format": "expanded",
            "extensionName": ".css",
            "savePath": "~/../css",
            //"savePath": null, 
            "savePathReplacementPairs": null
        }
    ],
    "liveSassCompile.settings.generateMap": false,
    "liveSassCompile.settings.useNewCompiler": false,
    "liveSassCompile.settings.autoprefix": [
    
    ],

 

php 에서도 컴포즈 같은걸로 다운 받으면 바로 자동 컴파일이 되면 좋겠지만 아쉽지만 요렇게 저장만 누르면 자동으로 컴파일을 해주니 상당히 편리한거 같다. php 는 곧 없어질거 같았지만 아직 의외로 많은 곳에서 쓰고 있고 버전업도 계속 되고 있어서 리액트나 뷰 처럼 변수가 동적으로 움직이는 시스템이 된다면 상당히 경쟁력이 있을거 같은데 그 점을 제외하면 서버비용도 저렴하고 코드도 쉽고 페이지도 빠르게 떠서 좋은거 같다. 

728x90
728x90

예시는 vue3 에서 vuetify 를 사용중일때 년/월/일 을 차례로 입력할때 enter key 로 자료를 빠르게 등록 하고자 할때 사용하면 유용한 스크립트 이다.  

<template>
  <VTextField
    ref="input1"
    maxlength="4"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
  />
  <VTextField
    ref="input2"
    maxlength="4"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
  />
  <VTextField
    ref="input3"
    maxlength="4"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
  />
</template>

<script setup>
import { ref } from 'vue';

function focusNextInput(event) {
  // 현재 입력 필드의 다음 형제 요소를 찾음
  const currentInput = event.target;
  const nextInput = currentInput.nextElementSibling;

  if (nextInput && nextInput.classList.contains('inputNext')) {
    nextInput.focus(); // 다음 입력 필드로 포커스 이동
  }
}
</script>

 

여러 필드가 있어도 dom 에서 그려지는 순서대로 이동하기 때문에 인덱스값 없이 함수 하나만 호출 하면 된다. 

 

아래 예제는 maxlength 값에 따라 글자수 만큼 채워지면 다음 칸으로 이동하는 스크립트다. 

<template>
  <VTextField
    ref="input1"
    :maxlength="4"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
    @input="checkInput($event)"
  />
  <VTextField
    ref="input2"
    :maxlength="2"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
    @input="checkInput($event)"
  />
  <VTextField
    ref="input3"
    :maxlength="4"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
    @input="checkInput($event)"
  />
  <VTextField
    ref="input4"
    :maxlength="3"
    variant="underlined"
    class="h-small inputNext"
    @keyup.enter="focusNextInput($event)"
    @input="checkInput($event)"
  />
</template>

<script setup>
import { ref } from 'vue';

function focusNextInput(event) {
  const currentInput = event.target;
  const nextInput = currentInput.nextElementSibling;

  if (nextInput && nextInput.classList.contains('inputNext')) {
    nextInput.focus();
  }
}

function checkInput(event) {
  const currentInput = event.target;
  const maxLength = currentInput.getAttribute('maxlength'); // maxlength 값 가져오기

  // 입력된 글자의 길이를 확인
  if (currentInput.value.length >= maxLength) {
    focusNextInput(event); // 다음 입력 필드로 포커스 이동
  }
}
</script>
728x90

+ Recent posts